package com.brogent;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;

import com.brogent.shapes.Shape;
import com.brogent.util.PngFilter;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

public class Painter extends Activity {

    /** image files directory */
    private static final String BMP_FILE_DIR      = "/sdcard/pic/";

    private int[]               color             = { R.drawable.green, R.drawable.blue, R.drawable.red };
    private int[]               text              = { R.string.str_green, R.string.str_blue, R.string.str_red };
    private int[]               tool              = { R.string.str_pen, R.string.str_line, R.string.str_rect, R.string.str_circle };

    public static byte          mToolType         = Shape.PEN;

    private final String        PREFIX            = "Pnt";
    private final String        PNG_EXT_NAME      = ".png";

    private final byte          FILE_SAVE_SUCCESS = 0x01;
    private final byte          FILE_SAVE_FAIL    = 0x02;
    private final byte          FILE_LOAD_SUCCESS = 0x03;
    private final byte          FILE_LOAD_FAIL    = 0x04;

    private Paint               mPaint            = PainterView.mPaint;

    /** The view responsible for drawing the window. */
    private PainterView         mView;
    private Handler             handler;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /** Set the color of line */
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(2);

        /** Create and attach the view that is responsible for painting. */
        mView = new PainterView(this);
        setContentView(mView);
        mView.requestFocus();

        handler = new MyHandler();
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.i(getClass().getSimpleName(), "onResume()");
    }

    @Override
    public void onRestart() {
        super.onRestart();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected(item);
        switch (item.getItemId()) {
            case R.id.open:
                openFile();
                break;
            case R.id.save:
                saveFile();
                break;
            case R.id.clear:
                mView.clear();
                break;
            case R.id.exit:
                finish();
                break;
            case R.id.tools:
                setTool();
                break;
            case R.id.colors:
                setColor();
                break;
            default:
                return super.onOptionsItemSelected(item);
        }
        return true;
    }

    private void openFile() {
        Intent intent = new Intent();
        intent.setClass(Painter.this, SelectFile.class);

        startActivityForResult(intent, 0);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.i(getClass().getSimpleName(), "onActivityResult()");
        if (resultCode == RESULT_OK) {
            switch (resultCode) {
                case RESULT_OK:
                    Bundle bundle = data.getExtras();

                    if (bundle == null) {
                        Log.i(getClass().getSimpleName(), "bundle is null");
                        return;
                    }

                    if ((!bundle.isEmpty()) && bundle.containsKey("path")) {
                        final String selectedPath = bundle.getString("path");
                        Log.i(getClass().getSimpleName(), selectedPath);

                        new Thread() {
                            @Override
                            public void run() {
                                super.run();
                                mView.loadImage(selectedPath);
                                Message m = new Message();
                                m.what = FILE_LOAD_SUCCESS;
                                handler.sendMessage(m);
                            }
                        }.start();
                    }
                    break;
                default:
                    break;
            }
        }
    }

    private void saveFile() {
        String fileName = new String("");

        File f = new File(BMP_FILE_DIR);
        if (!f.exists()) {
            new AlertDialog.Builder(this).setTitle("SD卡未插入").setPositiveButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                }
            }).show();
            return;
        }

        File[] bmpFiles = f.listFiles(new PngFilter());

        if (bmpFiles.length == 0) {
            fileName = PREFIX.concat("0000").concat(PNG_EXT_NAME);
        } else {
            for (int i = 0; i < bmpFiles.length; i++) {
                int serial;
                NumberFormat formatter = new DecimalFormat("0000");

                serial = Integer.valueOf(bmpFiles[i].getName().substring(3, 7));

                if (i != serial) {
                    fileName = PREFIX.concat(formatter.format(i)).concat(PNG_EXT_NAME);
                    break;
                }

                if (i == bmpFiles.length - 1) {
                    fileName = PREFIX.concat(formatter.format(i + 1)).concat(PNG_EXT_NAME);
                }
            }
        }

        final String absFilePath = BMP_FILE_DIR + fileName;
        new Thread() {
            @Override
            public void run() {
                Message m = new Message();
                try {
                    File tBmpFile = new File(absFilePath);
                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tBmpFile));
                    mView.mBitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);

                    bos.flush();
                    bos.close();

                    m.what = FILE_SAVE_SUCCESS;
                } catch (Exception e) {
                    Log.e(getClass().getSimpleName(), e.getMessage());
                    m.what = FILE_SAVE_FAIL;
                }
                handler.sendMessage(m);
            }
        }.start();
    }

    private void setTool() {
        new AlertDialog.Builder(Painter.this).setTitle(getResources().getString(R.string.str_title_tool)).setAdapter(
                new ToolAdapter(this, tool), toolListener).setPositiveButton("取消", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
            }
        }).show();
    }

    OnClickListener toolListener = new DialogInterface.OnClickListener() {
                                     public void onClick(DialogInterface dialog, int which) {
                                         switch (tool[which]) {
                                             case R.string.str_pen:
                                                 mView.setTool(Shape.PEN);
                                                 break;
                                             case R.string.str_line:
                                                 mView.setTool(Shape.LINE);
                                                 break;
                                             case R.string.str_rect:
                                                 mView.setTool(Shape.RECTANGLE);
                                                 break;
                                             case R.string.str_circle:
                                                 mView.setTool(Shape.CIRCLE);
                                                 break;
                                             default:
                                                 mView.setTool(Shape.PEN);
                                                 break;
                                         }

                                         Toast.makeText(Painter.this, getResources().getString(tool[which]), Toast.LENGTH_SHORT)
                                                 .show();
                                     }
                                 };

    private void setColor() {
        new AlertDialog.Builder(Painter.this).setTitle(getResources().getString(R.string.str_title_color)).setAdapter(
                new ColorAdapter(this, color, text), colorListener).setPositiveButton("取消",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                    }
                }).show();
    }

    OnClickListener colorListener = new DialogInterface.OnClickListener() {
                                      public void onClick(DialogInterface dialog, int which) {
                                          /**
                                           * problems to be fixed here, 20080918
                                           */
                                          switch (color[which]) {
                                              case R.drawable.green:
                                                  mPaint.setColor(Color.GREEN);
                                                  break;
                                              case R.drawable.blue:
                                                  mPaint.setColor(Color.BLUE);
                                                  break;
                                              case R.drawable.red:
                                                  mPaint.setColor(Color.RED);
                                                  break;
                                          }

                                          Toast.makeText(Painter.this, getResources().getString(text[which]), Toast.LENGTH_SHORT)
                                                  .show();
                                      }
                                  };

    protected void showInfo(String mesg) {
        new AlertDialog.Builder(this).setIcon(R.drawable.icon).setTitle(mesg).setPositiveButton("OK",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                    }
                }).show();
    }

    class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case FILE_SAVE_SUCCESS:
                    Log.i(getClass().getSimpleName(), "FILE_SAVE_SUCCESS");
                    break;
                case FILE_SAVE_FAIL:
                    Log.i(getClass().getSimpleName(), "FILE_SAVE_FAIL");
                    break;
                case FILE_LOAD_SUCCESS:
                    Log.i(getClass().getSimpleName(), "FILE_LOAD_SUCCESS");
                    mView.invalidate();
                    break;
                case FILE_LOAD_FAIL:
                    Log.i(getClass().getSimpleName(), "FILE_LOAD_FAIL");
                    break;
            }
            super.handleMessage(msg);
        }
    }
}